import 'dart:math';

import 'package:flame/components.dart';
import 'package:flutter/material.dart';
import 'package:study_demo/ui/game/damage_text.dart';

mixin Liveable on PositionComponent {
  final Paint _outlinePaint = Paint();
  final Paint _fillPaint = Paint();
  late double lifePoint; // 生命上限
  late double _currentLife; // 当前生命值

  final TextStyle _textStyle =
      const TextStyle(fontSize: 10, color: Colors.white);
  late final TextComponent _text;
  final double offSetY = 10; //血条距构件顶部的偏移量
  final double widthRadio = 1.5; //血条构件宽度
  final double lifeBarHeight = 4; //血条高度

  final DamageText _damageText = DamageText();

  void initPaint(
      {required double lifePoint,
      Color lifeColor = Colors.red,
      Color outlineColor = Colors.white}) {
    _outlinePaint
      ..color = outlineColor
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1;
    _fillPaint.color = lifeColor;
    this.lifePoint = lifePoint;
    _currentLife = lifePoint;
    _text = TextComponent(textRenderer: TextPaint(style: _textStyle));
    double y = -(offSetY + _text.height + 2);
    double x = (size.x / 2) * (1.7 - widthRadio);
    _text.position = Vector2(x, y);
    add(_text);
    add(_damageText);
  }

  double get _progress => _currentLife / lifePoint;

  @override
  void render(Canvas canvas) {
    super.render(canvas);

    Rect rect = Rect.fromCenter(
        center: Offset(size.x / 2, lifeBarHeight / 2 - offSetY),
        width: size.x / 2 * widthRadio,
        height: lifeBarHeight);
    Rect lifeRect = Rect.fromPoints(
        rect.topLeft + Offset(rect.width * (1 - _progress), 0),
        rect.bottomRight);
    canvas.drawRect(lifeRect, _fillPaint);
    canvas.drawRect(rect, _outlinePaint);
  }

  final Random _random = Random();

  void loss(double point) {
    _currentLife -= point;
    _updateLifeText();
    double crit = 0.75;
    double critImage = 1.65;
    bool isCrit = _random.nextDouble() < crit;
    if (isCrit) {
      point = point * critImage;
    }
    _damageText.addImage(-point.toInt(), isCrit: isCrit);
    if (_currentLife <= 0) {
      _currentLife = 0;
      onDied();
    }
  }

  void onDied() {}

  void _updateLifeText() {
    _text.text = 'Hp ${_currentLife.toString()}';
  }
}
